<?php
/**
 * Module GuestBook
 *
 * @author develx
 */
class GuestBook extends Module {
    protected $name = 'GuestBook';
    protected $administrable = true;
    protected $version = '2010-08-19';
    protected $details = array('dependencies' => array('AntiCaptcha'),
            'observes' => array('GuestBook'));

    const POSTS = 'guestBook';

    protected $postsTable = array('id' => 'iPN+', 'response' => 'iNI',
            'title' => "v'512'", 'text' => 'T', 'author' => 's', 'email' =>
            's', 'webpage' => 's', 'responseLevel' => 'iN');

    protected $postRecord = array('table' => self::POSTS, 'data' => array());

    protected $itemsOnPage = 20;
    protected $minDelay = 3;

    public function __construct(DBAPI $dbapi, RecordList $recordList) {
        parent::__construct($dbapi, $recordList);
        $this->postRecord['properties'] = $this->postsTable;
    }

    public function install() {
        Modules::getModule('Users')->registerRights($this->getName(),
                $this->getRights());
        return $this->dbdriver->createTable(self::POSTS, $this->postsTable);
    }

    public function uninstall() {
        return $this->dbdriver->dropTable(self::POSTS);
    }

    public function onAdd(&$details, $source) {
        Kernel::setRedirect($this->getLink());
        if (!Modules::getModule('AntiCaptcha')->checkCode()) {
            return;
        }
        if (!isset($_SESSION['guestBookViewed']) ||
                !$_SESSION['guestBookViewed'] ||
                (time() - $_SESSION['guestBookViewed']) < $this->minDelay) {
            $_SESSION['guestBookViewed'] = null;
            unset($_SESSION['guestBookViewed']);
            return;
        }
        $_SESSION['guestBookViewed'] = null;
        unset($_SESSION['guestBookViewed']);
        setcookie('GuestBookAuthor', $details['author'], time() + 84600 * 365,
                '/', Config::DOMAIN_NAME);
        setcookie('GuestBookEmail', $details['email'], time() + 84600 * 365,
                '/', Config::DOMAIN_NAME);
        setcookie('GuestBookWWW', $details['webpage'], time() + 84600 * 365,
                '/', Config::DOMAIN_NAME);
        $post = $this->fillRecord($this->postRecord, $details);
        if ($details['response'] == 0) {
            $post['data']['responseLevel'] = 0;
        } else {
            $cols = array('responseLevel');
            $level = &$this->dbdriver->select(self::POSTS, $cols, '`id` = ' .
                    $details['response']);
            $post['data']['responseLevel'] = $level[0]['responseLevel'] + 1;
        }
        $this->dbapi->save($post);
    }

    public function onDelete(&$details, $source) {
        Kernel::setRedirect($this->getLink());
        if (!$this->hasRights('view admin')) {
            return;
        }
        if ((int) $details == 0) {
            return;
        }
        $this->delete((int) $details);
    }

    public function initDisplayPublicIndex() {
        $this->js('/utils/tiny_mce/tiny_mce.js', false);
        $this->js('/wysiwyg.js');
        $this->js('/guestbook.js');
        Modules::getModule('AntiCaptcha')->initDisplayBlank();
    }

    public function displayAdminIndex() {
        $posts = &$this->getAdminPosts();
        $params = array('posts' => &$posts);
        $this->template('adminlist', $params);
    }

    public function displayPublicIndex($page = 1) {
        if (!isset($_SESSION['guestBookViewed']) ||
                !$_SESSION['guestBookViewed']) {
            $_SESSION['guestBookViewed'] = time();
        }
        $cols = array('COUNT(*)');
        $pages = &$this->dbdriver->select(self::POSTS, $cols,
                '`response` = 0');
        $pages = max(1, ceil($pages[0]['COUNT(*)'] / $this->itemsOnPage));
        $page = max(1, min($page, $pages));
        $posts = &$this->getPosts($page);
        $params = array('posts' => &$posts, 'paging' => array('linkPreffix' =>
                $this->getLink('index/'), 'linkSuffix' => '/', 'current' =>
                $page, 'count' => $pages), 'form' => $this->getAddForm());
        $this->template('posts', $params);
    }

    private function delete($id) {
        $cols = array('id');
        $sub = &$this->dbdriver->select(self::POSTS, $cols,
                "`response` = $id");
        foreach ($sub as $post) {
            $this->delete($post['id']);
        }
        $this->dbdriver->delete(self::POSTS, "`id` = $id");
    }

    private function &getAdminPosts($response = 0) {
        $cols = array();
        $order = array($response == 0 ? '!id' : 'id');
        $posts = array();
        $loaded = &$this->dbdriver->select(self::POSTS, $cols,
                "`response` = $response", $order);
        foreach ($loaded as &$post) {
            $post['delete'] = $this->getLink($post['id'], 'delete');
            $posts[] = $post;
            $sub = &$this->getAdminPosts($post['id']);
            $posts = array_merge($posts, $sub);
        }
        return $posts;
    }

    private function getAddForm($response = 0) {
        $form = array('start' => 'add', 'legend' => 'addForm', 'submit' =>
                'post', 'items' => array());
        $form['items'][] = array('name' => 'author', 'label' => 'author');
        $form['items'][] = array('name' => 'email', 'label' => 'email');
        $form['items'][] = array('name' => 'webpage', 'label' => 'webpage');
        $form['items'][] = array('name' => 'title', 'label' => 'title');
        $form['items'][] = array('name' => 'text', 'label' => 'text',
                'type' => 'textarea', 'cols' => 80, 'rows' => 5);
        $form['items'][] = array('name' => 'response', 'value' => $response,
                'type' => 'hidden');
        if (isset($_COOKIE['GuestBookAuthor'])) {
            $form['items'][0]['value'] = $_COOKIE['GuestBookAuthor'];
        }
        if (isset($_COOKIE['GuestBookEmail'])) {
            $form['items'][1]['value'] = $_COOKIE['GuestBookEmail'];
        }
        if (isset($_COOKIE['GuestBookWWW'])) {
            $form['items'][2]['value'] = $_COOKIE['GuestBookWWW'];
        }
        $this->prepareFormData($form);
        return $form;
    }

    private function &getPosts($page, $response = 0) {
        $cols = array('id', 'title', 'text', 'author', 'webpage',
                'responseLevel');
        $order = array($response == 0 ? '!id' : 'id');
        if ($response == 0) {
            $loaded = &$this->dbdriver->select(self::POSTS, $cols,
                    "`response` = 0", $order, ($page - 1) * $this->itemsOnPage,
                    $this->itemsOnPage);
        } else {
            $loaded = &$this->dbdriver->select(self::POSTS, $cols,
                    "`response` = $response", $order);
        }
        $posts = array();
        foreach ($loaded as &$post) {
            $posts[] = $post;
            $sub = &$this->getPosts(0, $post['id']);
            $posts = array_merge($posts, $sub);
        }
        return $posts;
    }
}
?>
